home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / UTILITY1 / MSWSRC35.ZIP / GRAPHICS.CPP < prev    next >
C/C++ Source or Header  |  1993-08-26  |  28KB  |  1,314 lines

  1. /*
  2.  *      graphics.c          logo graphics module          mak
  3.  *
  4.  *    Copyright (C) 1989 The Regents of the University of California
  5.  *    This Software may be copied and distributed for educational,
  6.  *    research, and not for profit purposes provided that this
  7.  *    copyright and statement are included in all such copies.
  8.  *
  9.  */
  10.  
  11. #include "logo.h"
  12. /*   #include "globals.h"   has been moved further down */
  13. #include <math.h>
  14.  
  15. #ifdef mac
  16. #include "macterm.h"
  17. #else
  18. #ifdef ibm
  19. #ifdef __ZTC__
  20. #include <fg.h>
  21. #include "ztcterm.h"
  22. #else
  23. //ggm#include "ibmterm.h"
  24. #endif
  25. #else
  26. #ifdef x_window
  27. #include "xgraphics.h"
  28. #else
  29. #include "nographics.h"
  30. #endif
  31. #endif
  32. #endif
  33.  
  34. #include "globals.h"
  35.  
  36. #ifdef __ZTC__
  37. #define total_turtle_bottom_max (-(MaxY/2))
  38. #else
  39. #define total_turtle_bottom_max turtle_bottom_max
  40. #endif
  41.  
  42. extern int status_flag;
  43.  
  44. /* NOTE: See the files (macterm.c and macterm.h) or (ibmterm.c and ibmterm.h)
  45.    for examples of the functions and macros that this file assumes exist. */
  46.  
  47. mode_type current_mode = wrapmode;
  48. FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0;
  49. BOOLEAN turtle_shown = TRUE;
  50. FLONUM x_scale = 1.0, y_scale = 1.0;
  51. FLONUM wanna_x = 0.0, wanna_y = 0.0;
  52. BOOLEAN out_of_bounds = FALSE;
  53.  
  54. //char record[GR_SIZE];
  55. int record_index = 0;
  56. pen_info orig_pen;
  57. int forward_count = 0;
  58.  
  59. BOOLEAN record_next_move = FALSE, refresh_p = TRUE;
  60.  
  61. /************************************************************/
  62.  
  63. double pfmod(double x, double y) {
  64.     double temp = fmod(x,y);
  65.  
  66.     if (temp < 0) return temp+y;
  67.     return temp;
  68. }
  69.  
  70. FLONUM cut_error(FLONUM n)
  71. {
  72.     n *= 1000000.0;
  73.     n = (n > 0.0 ? floor(n) : ceil(n));
  74.     n /= 1000000.0;
  75.     if (n == -0.0) n = 0.0;
  76.     return(n);
  77. }
  78.  
  79. FIXNUM g_round(FLONUM n)
  80. {
  81.     n += (n < 0.0 ? -0.5 : 0.5);
  82.     if (n < 0.0)
  83.     return((FIXNUM)ceil(n));
  84.     return((FIXNUM)floor(n));
  85. }
  86.  
  87. /************************************************************/
  88.  
  89. void draw_turtle()
  90. {
  91.     if (turtle_shown) ibmturt(0);
  92.     return;
  93.  
  94.     draw_turtle_helper();
  95.     /* all that follows is for "turtle wrap" effect */
  96.     if ((turtle_y > turtle_top_max - turtle_height) &&
  97.         (current_mode == wrapmode)) {
  98.     turtle_y -= (screen_height + 1);
  99.     draw_turtle_helper();
  100.     check_x_high();
  101.     check_x_low();
  102.     turtle_y += (screen_height + 1);
  103.     }
  104.     if ((turtle_y < turtle_bottom_max + turtle_height) &&
  105.         (current_mode == wrapmode)) {
  106.     turtle_y += (screen_height + 1);
  107.     draw_turtle_helper();
  108.     check_x_high();
  109.     check_x_low();
  110.     turtle_y -= (screen_height + 1);
  111.     }
  112.     check_x_high();
  113.     check_x_low();
  114. }
  115.  
  116. void check_x_high()
  117. {
  118.     if ((turtle_x > turtle_right_max - turtle_height) &&
  119.         (current_mode == wrapmode)) {
  120.     turtle_x -= (screen_width + 1);
  121.     draw_turtle_helper();
  122.     turtle_x += (screen_width + 1);
  123.     }
  124. }
  125.  
  126. void check_x_low()
  127. {
  128.     if ((turtle_x < turtle_left_max + turtle_height) &&
  129.         (current_mode == wrapmode)) {
  130.     turtle_x += (screen_width + 1);
  131.     draw_turtle_helper();
  132.     turtle_x -= (screen_width + 1);
  133.     }
  134. }
  135.  
  136. void draw_turtle_helper()
  137. {
  138.   ibmturt(0);
  139. }
  140.  
  141. /*
  142. draw_turtle_helper()
  143. {
  144.     pen_info saved_pen;
  145.     FLONUM real_heading;
  146.     int left_x, left_y, right_x, right_y, top_x, top_y, center_x, center_y;
  147.     
  148.     prepare_to_draw;
  149.     prepare_to_draw_turtle;
  150.     save_pen(&saved_pen);
  151.     plain_xor_pen();
  152.     pen_vis = 0;
  153.     
  154.     real_heading = -turtle_heading + 90.0;
  155.     center_x = screen_right/2;
  156. #ifdef __ZTC__
  157.     center_y = MaxY/2;
  158. #else
  159.     center_y = screen_bottom/2;
  160. #endif
  161.     
  162.     left_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom));
  163.     left_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom));
  164.  
  165.     right_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom));
  166.     right_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom));
  167.  
  168.     top_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)(real_heading*degrad))*turtle_side));
  169.     top_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)(real_heading*degrad))*turtle_side));
  170.  
  171.     move_to(center_x + left_x, center_y - left_y);
  172.     line_to(center_x + top_x, center_y - top_y);
  173.     move_to(center_x + right_x, center_y - right_y);
  174.     line_to(center_x + top_x, center_y - top_y);
  175.     move_to(center_x + left_x, center_y - left_y);
  176.     line_to(center_x + right_x, center_y - right_y);
  177.  
  178.     restore_pen(&saved_pen);
  179.     done_drawing_turtle;
  180.     done_drawing;
  181. }
  182. */
  183.  
  184. /************************************************************/
  185.  
  186. void right(FLONUM a)
  187. {
  188.     draw_turtle();
  189.     turtle_heading += a;
  190.     turtle_heading = pfmod(turtle_heading,360.0);
  191.     if (status_flag) update_status_turtleheading();
  192.     draw_turtle();
  193. }
  194.  
  195. NODE *numeric_arg(NODE *args)
  196. {
  197.     NODE *arg = car(args), *val;
  198.  
  199.     val = cnv_node_to_numnode(arg);
  200.     while (val == UNBOUND && NOT_THROWING) {
  201.     gcref(val);
  202.     setcar(args, err_logo(BAD_DATA, arg));
  203.     arg = car(args);
  204.     val = cnv_node_to_numnode(arg);
  205.     }
  206.     setcar(args,val);
  207.     return(val);
  208. }
  209.  
  210. NODE *lright(NODE *arg)
  211. {
  212.     NODE *val;
  213.     FLONUM a;
  214.     
  215.     val = numeric_arg(arg);
  216.     if (NOT_THROWING) {
  217.     if (nodetype(val) == INT)
  218.         a = (FLONUM)getint(val);
  219.     else
  220.         a = getfloat(val);
  221.     right(a);
  222.     }
  223.     return(UNBOUND);
  224. }
  225.  
  226. NODE *lleft(NODE *arg)
  227. {
  228.     NODE *val;
  229.     FLONUM a;
  230.     
  231.     val = numeric_arg(arg);
  232.     if (NOT_THROWING) {
  233.     if (nodetype(val) == INT)
  234.         a = (FLONUM)getint(val);
  235.     else
  236.         a = getfloat(val);
  237.     right(-a);
  238.     }
  239.     return(UNBOUND);
  240. }
  241.  
  242. NODE *larc(NODE *arg)
  243. {
  244.     NODE *val1;
  245.     NODE *val2;
  246.  
  247.     FLONUM angle;
  248.     FLONUM radius;
  249.     FLONUM ang;
  250.     FLONUM tx;
  251.     FLONUM ty;
  252. //    FLONUM oldx;
  253. //    FLONUM oldy;
  254.     FLONUM x;
  255.     FLONUM y;
  256.     FLONUM count;
  257.     FLONUM delta;
  258.     FLONUM i;
  259.  
  260.     int turtle_state;
  261.     int pen_state;
  262.     
  263.     /* get args */
  264.  
  265.     val1 = numeric_arg(arg);
  266.     val2 = numeric_arg(cdr(arg));
  267.  
  268.     if (NOT_THROWING) {
  269.  
  270.     if (nodetype(val1) == INT)
  271.         angle = (FLONUM)getint(val1);
  272.     else
  273.         angle = getfloat(val1);
  274.  
  275.     if (nodetype(val2) == INT)
  276.         radius = (FLONUM)getint(val2);
  277.     else
  278.         radius = getfloat(val2);
  279.  
  280.     prepare_to_draw;
  281.     draw_turtle();
  282.  
  283.     /* save and force turle state */
  284.  
  285.     turtle_state = turtle_shown;
  286.     turtle_shown = 0;
  287.  
  288.     /* grab things before they change and use for restore */
  289.  
  290.     ang = turtle_heading;
  291.     tx = turtle_x;
  292.     ty = turtle_y;
  293.  
  294.     /* calculate resolution parameters */
  295.  
  296.     count = abs(angle*radius/200.0);
  297.     delta = angle/count;
  298.  
  299.     /* draw each line segment of arc (will do wrap) */
  300.  
  301.     for (i=0.0;i<=count;i=i+1.0)
  302.        {
  303.  
  304.        /* calc x y */
  305.  
  306.        x = -sin(ang*3.141592654/180.0)*radius;
  307.        y = -cos(ang*3.141592654/180.0)*radius;
  308.  
  309.        /* jump to begin of first line segment without drawing */
  310.  
  311.        if (i==0.0)
  312.           {
  313.           pen_state = pen_vis;
  314.           pen_vis = 1;
  315.           setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
  316.           pen_vis = pen_state;
  317.           }
  318.  
  319.        /* else do segment */
  320.  
  321.        else
  322.           {
  323.           setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
  324.           }
  325.  
  326.        ang = ang + delta;
  327.        }
  328.  
  329.     /* assure we draw something and end in the exact right place */
  330.  
  331.     x = -sin((turtle_heading+angle)*3.141592654/180.0)*radius;
  332.     y = -cos((turtle_heading+angle)*3.141592654/180.0)*radius;
  333.  
  334.     setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
  335.  
  336.     /* restore state */
  337.  
  338.     turtle_shown = turtle_state;
  339.  
  340.     turtle_x = tx;
  341.     turtle_y = ty;
  342.  
  343.     draw_turtle();
  344.     done_drawing;
  345.     wanna_x = turtle_x;
  346.     wanna_y = turtle_y;
  347.     out_of_bounds = FALSE;
  348.  
  349.     }
  350.     return(UNBOUND);
  351. }
  352.  
  353. void forward(FLONUM d)
  354. {
  355.     prepare_to_draw;
  356.     draw_turtle();
  357.     forward_helper(d);
  358.     draw_turtle();
  359.     done_drawing;
  360.     wanna_x = turtle_x;
  361.     wanna_y = turtle_y;
  362.     out_of_boun